﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace MacomberMapSystem.Common.Exports
{
    /// <summary>
    /// This query is used to assist in developing outgoing queries
    /// </summary>
    public class MM_DDL_Query
    {
        #region Variable declarations
        /// <summary>The outgoing XML document</summary>
        XmlDocument OutDoc = new XmlDocument();
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize our outgoing document
        /// </summary>
        public MM_DDL_Query()
        {
            XmlElement BaseElement = OutDoc.CreateElement("qns", "simpleQuery", "uuid:14F5F723-831B-46c8-AF5F-0E0D69315B6F");
            //BaseElement.Attributes.Append(OutDoc.CreateAttribute("xmlns:qns")).Value = "uuid:14F5F723-831B-46c8-AF5F-0E0D69315B6F";
            BaseElement.Attributes.Append(OutDoc.CreateAttribute("refresh")).Value = "4";
            BaseElement.Attributes.Append(OutDoc.CreateAttribute("guid")).Value = Guid.NewGuid().ToString();
            BaseElement.Attributes.Append(OutDoc.CreateAttribute("compress")).Value = "true";
            OutDoc.AppendChild(BaseElement);
        }
        #endregion

        #region Field addition
        /// <summary>
        /// Add a field to the outgoing XML.
        /// </summary>
        /// <param name="Application"></param>
        /// <param name="Database"></param>
        /// <param name="Record"></param>
        /// <param name="Field"></param>
        public void AddField(String Application, String Database, String Record, String Field)
        {
            XmlElement Rec = LocateRecord(Application, Database, Record);

            String[] splStr = Field.Replace("$", "__").Split('>');
            XmlElement NewVal = OutDoc.CreateElement("fld");
            for (int a = 0; a < splStr.Length; a++)
                if (a == 0)
                    NewVal.Attributes.Append(OutDoc.CreateAttribute("name")).Value = splStr[a];
                else
                {
                    XmlElement xCh = OutDoc.CreateElement("indFld");
                    xCh.Attributes.Append(OutDoc.CreateAttribute("name")).Value = splStr[a];
                    NewVal.AppendChild(xCh);
                }
            Rec.AppendChild(NewVal);
        }

        /// <summary>
        /// Locate or create a record
        /// </summary>
        /// <param name="Application"></param>
        /// <param name="Database"></param>
        /// <param name="Record"></param>
        /// <returns></returns>
        private XmlElement LocateRecord(String Application, String Database, String Record)
        {
            XmlElement App = null, Db = null, Rec = null;
            foreach (XmlElement xElem in OutDoc.DocumentElement.ChildNodes)
                if (xElem.Attributes["name"].Value == Application)
                    App = xElem;

            if (App == null)
            {
                App = OutDoc.CreateElement("app");
                App.Attributes.Append(OutDoc.CreateAttribute("name")).Value = Application;
                OutDoc.DocumentElement.AppendChild(App);
            }

            foreach (XmlElement xElem in App.ChildNodes)
                if (xElem.Attributes["name"].Value == Database)
                    Db = xElem;
            
            if (Db == null)
            {
                Db = OutDoc.CreateElement("db");
                Db.Attributes.Append(OutDoc.CreateAttribute("name")).Value = Database;
                App.AppendChild(Db);
            }

            foreach (XmlElement xElem in Db.ChildNodes)
                if (xElem.Attributes["name"].Value == Record)
                    Rec = xElem;
            
            if (Rec == null)
            {
                Rec = OutDoc.CreateElement("rec");
                Rec.Attributes.Append(OutDoc.CreateAttribute("name")).Value = Record;
                Db.AppendChild(Rec);
            }
            return Rec;
        }

        /// <summary>
        /// Add a key to our database
        /// </summary>
        /// <param name="Application"></param>
        /// <param name="Database"></param>
        /// <param name="Record"></param>
        /// <param name="Keys"></param>
        public void AddKey(String Application, String Database, String Record, params String[] Keys)
        {
            XmlElement NewRec = OutDoc.CreateElement("qns", "key", "uuid:14F5F723-831B-46c8-AF5F-0E0D69315B6F");
            foreach (String keyvalue in Keys)
            {
                XmlElement KeyPart = OutDoc.CreateElement("keyPart");
                KeyPart.Attributes.Append(OutDoc.CreateAttribute("rec")).Value = keyvalue.Split('=')[0];
                KeyPart.Attributes.Append(OutDoc.CreateAttribute("val")).Value = keyvalue.Split('=')[1].ToUpper();
                NewRec.AppendChild(KeyPart);
            }
            LocateRecord(Application, Database, Record).AppendChild(NewRec);
        }

        #endregion

        /// <summary>
        /// Write out our full element
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            UTF8Encoding UTF8 = new UTF8Encoding(false);
            using (MemoryStream mS = new MemoryStream())
            using (XmlTextWriter xW = new XmlTextWriter(mS, UTF8))
            {
                xW.Namespaces = true;
                xW.Formatting = Formatting.Indented;
                xW.WriteStartDocument();
                OutDoc.WriteTo(xW);
                xW.Flush();
                return UTF8.GetString(mS.ToArray());
            }

        }
    }
}
